home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / XPK / Source / xpkmaster / password.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-12  |  8.5 KB  |  312 lines

  1. #ifndef XPKMASTER_PASSWORD_C
  2. #define XPKMASTER_PASSWORD_C
  3.  
  4. /* Routinesheader
  5.  
  6.     Name:        password.c
  7.     Main:        xpkmaster
  8.     Versionstring:    $VER: password.c 1.5 (10.04.97)
  9.     Author:        SDI
  10.     Distribution:    PD
  11.     Description:    password requester related things
  12.  
  13.  1.0   27.12.96 : first version
  14.  1.1   28.12.96 : starting to code the stuff
  15.  1.2   29.12.96 : optimized and removed bugs
  16.  1.3   02.01.97 : corrected return handling
  17.  1.4   01.03.97 : fixed tag parsing error
  18.  1.5   10.04.97 : now old screen comes to front after Request
  19. */
  20.  
  21. #include <pragma/intuition_lib.h>
  22. #include <pragma/exec_lib.h>
  23. #include <pragma/utility_lib.h>
  24. #include <exec/types.h>
  25. #include <exec/memory.h>
  26. #include <intuition/sghooks.h>
  27. #include <intuition/intuitionbase.h>
  28. #include <xpk/xpk.h>
  29. #include <xpk/xpkprefs.h>
  30. #include "xpk_strings.h"
  31. #include "xpkmaster.h"
  32.  
  33. #ifdef __MAXON__
  34.   #define __asm
  35. #endif
  36.  
  37. #define TESTSIZE    13
  38.  
  39. static struct PassCharData {
  40.   ULONG Flag;
  41.   UBYTE Lower;
  42.   UBYTE Upper;
  43. } TestField[TESTSIZE] = {
  44. {XPKPASSFF_30x39,0x30,0x39}, {XPKPASSFF_41x46,0x41,0x46},
  45. {XPKPASSFF_61x66,0x61,0x66}, {XPKPASSFF_47x5A,0x47,0x5A},
  46. {XPKPASSFF_67x7A,0x67,0x7A}, {XPKPASSFF_20,   0x20,0x20},
  47. {XPKPASSFF_SPECIAL7BIT,0x21,0x2F},
  48. {XPKPASSFF_SPECIAL7BIT,0x3A,0x40},
  49. {XPKPASSFF_SPECIAL7BIT,0x5B,0x60},
  50. {XPKPASSFF_SPECIAL7BIT,0x7B,0x7F},
  51. {XPKPASSFF_C0xDE,0xC0,0xDE}, {XPKPASSFF_DFxFF,0xDF,0xFF},
  52. {XPKPASSFF_SPECIAL8BIT,0xA0,0xBF},
  53. };
  54.  
  55. struct PassUserData {
  56.   ULONG pud_Flags;
  57.   UBYTE pud_Entered;
  58. };
  59.  
  60. static ULONG __asm PassHookFunc(register __a0 struct Hook *hook,
  61. register __a2 struct SGWork *sgw, register __a1 ULONG *msg)
  62. {
  63. // clear the time request here
  64.   ((struct PassUserData *) sgw->Gadget->UserData)->pud_Entered = 1;
  65.  
  66.   if(*msg == SGH_KEY)
  67.   {
  68.     if((sgw->EditOp == EO_REPLACECHAR) || (sgw->EditOp == EO_INSERTCHAR))
  69.     {
  70.       register ULONG i, f = ((struct PassUserData *) sgw->Gadget->UserData)->pud_Flags;
  71.       register UBYTE c = sgw->Code;
  72.  
  73.       for(i = 0; i < TESTSIZE; ++i)
  74.       {
  75.         if((f & TestField[i].Flag) && (c >= TestField[i].Lower) &&
  76.         (c <= TestField[i].Upper))
  77.           break;
  78.       }
  79.       if(i == TESTSIZE)
  80.       {
  81.         sgw->Actions |= SGA_BEEP; // let the screen beep
  82.         sgw->Actions &= ~SGA_USE; // do not use char
  83.       }
  84.     }
  85.     return ~0;
  86.   }
  87.   else
  88.     return 0;
  89. }
  90.  
  91. static struct Hook PassHook = { {0}, (ULONG (*) ()) PassHookFunc, 0, 0};
  92.  
  93. struct RequestData {
  94.   ULONG            rd_MaxTicks;
  95.   ULONG            rd_Time;
  96.   STRPTR        rd_Title;
  97.   STRPTR        rd_GivenBuffer;
  98.   struct Screen *    rd_Screen;
  99.   struct Screen *    rd_FirstScreen;
  100.   struct Screen *    rd_SelfScreen;
  101.   struct Window    *    rd_Window;
  102.   struct DrawInfo *    rd_DrawInfo;
  103.   struct PassUserData    rd_PassUserData;
  104.   struct Gadget        rd_Gadget;
  105.   struct StringInfo    rd_StringInfo;
  106.   struct StringExtend    rd_StringExtend;
  107.   UBYTE            rd_KeyBuffer[9];
  108.   UBYTE            rd_ScreenTitle[80];
  109. };
  110.  
  111. #define passbuf        rd->rd_StringInfo.Buffer
  112. #define passsize    rd->rd_StringInfo.MaxChars
  113.  
  114. /* returns XPKERR codes */
  115. static LONG DoRequest(struct RequestData *rd)
  116. {
  117.   LONG ticks = XPKERR_UNKNOWN;
  118.   
  119.   rd->rd_MaxTicks = rd->rd_Time << 3; /* *8, seems to be correct factor */
  120.   *passbuf = 0;
  121.  
  122.   if(!rd->rd_Screen && !(rd->rd_Screen = rd->rd_SelfScreen = LockPubScreen(0)))
  123.     return XPKERR_UNKNOWN;
  124.  
  125.   if((rd->rd_DrawInfo = GetScreenDrawInfo(rd->rd_Screen)))
  126.   {
  127.     rd->rd_Gadget.TopEdge    = rd->rd_Screen->WBorTop;
  128.     rd->rd_Gadget.LeftEdge    = rd->rd_Screen->WBorLeft;
  129.     rd->rd_Gadget.Width        = rd->rd_Screen->Width >> 1;
  130.     rd->rd_Gadget.Height    = rd->rd_Screen->Font->ta_YSize;
  131.     rd->rd_Gadget.Flags        = GFLG_GADGHNONE | GFLG_STRINGEXTEND;
  132.     rd->rd_Gadget.Activation    = GACT_RELVERIFY | GACT_STRINGCENTER;
  133.     rd->rd_Gadget.GadgetType    = GTYP_STRGADGET;
  134.     rd->rd_Gadget.SpecialInfo    = &rd->rd_StringInfo;
  135.     rd->rd_Gadget.UserData    = (APTR) &rd->rd_PassUserData;
  136.     rd->rd_StringInfo.Extension    = &rd->rd_StringExtend;
  137.     rd->rd_StringExtend.Pens[0] =
  138.     rd->rd_StringExtend.Pens[1] =
  139.     rd->rd_StringExtend.ActivePens[0] =
  140.     rd->rd_StringExtend.ActivePens[1] = rd->rd_DrawInfo->dri_Pens[BACKGROUNDPEN];
  141.     rd->rd_StringExtend.EditHook      = &PassHook;
  142.     rd->rd_StringExtend.WorkBuffer    =
  143.       AllocMem(passsize, MEMF_ANY|MEMF_CLEAR);
  144.  
  145.     if((rd->rd_Window = OpenWindowTags(0,
  146.     WA_Left,    (rd->rd_Screen->Width  - rd->rd_Gadget.Width  -
  147.             rd->rd_Screen->WBorLeft - rd->rd_Screen->WBorRight)>>1,
  148.     WA_Top,        (rd->rd_Screen->Height - rd->rd_Gadget.Height -
  149.             rd->rd_Screen->WBorTop  - rd->rd_Screen->WBorBottom)>>1,
  150.     WA_InnerWidth,    rd->rd_Gadget.Width,
  151.     WA_InnerHeight,    rd->rd_Gadget.Height,
  152.     WA_Gadgets,    &rd->rd_Gadget,
  153.     WA_IDCMP,    IDCMP_GADGETUP | IDCMP_ACTIVEWINDOW | IDCMP_INTUITICKS | IDCMP_RAWKEY,
  154.     WA_Flags,    WFLG_ACTIVATE | WFLG_RMBTRAP,
  155.     WA_PubScreen,    rd->rd_Screen,
  156.     WA_PubScreenFallBack,    TRUE,
  157.     (rd->rd_Title ? WA_ScreenTitle : TAG_IGNORE), rd->rd_Title,
  158.     TAG_DONE)))
  159.     {
  160.       struct IntuiMessage *msg;
  161.       BOOL stop = 0;
  162.  
  163.       ticks = 0;
  164.       rd->rd_FirstScreen = IntuitionBase->FirstScreen;
  165.       ScreenToFront(rd->rd_Screen);
  166.       while(!stop)
  167.       {
  168.     WaitPort(rd->rd_Window->UserPort);
  169.     while(!stop && (msg = (struct IntuiMessage *)
  170.     GetMsg(rd->rd_Window->UserPort)))
  171.     {
  172.       if(msg->Class == IDCMP_INTUITICKS)
  173.         ++ticks;
  174.       else
  175.         ticks = 0;
  176.  
  177.       switch(msg->Class)
  178.       {
  179.       case IDCMP_ACTIVEWINDOW:
  180.         ActivateGadget(&rd->rd_Gadget, rd->rd_Window, 0); break;
  181.       case IDCMP_GADGETUP: stop = 1; break;
  182.       case IDCMP_RAWKEY: if(msg->Code = 0x45) stop = 2; break; /* ESC */
  183.           }
  184.       ReplyMsg((struct Message *) msg);
  185.     }
  186.     if(rd->rd_PassUserData.pud_Entered)
  187.     {
  188.       rd->rd_PassUserData.pud_Entered = 0; ticks = 0;
  189.     }
  190.         if(((ticks >= rd->rd_MaxTicks) && rd->rd_Time))
  191.           stop = 2;
  192.       }
  193.       ticks = (stop > 1 || !*passbuf) ? XPKERR_ABORTED : XPKERR_OK;
  194.       CloseWindow(rd->rd_Window);
  195.       if(rd->rd_FirstScreen != rd->rd_Screen)
  196.       {
  197.         struct Screen *sc;
  198.         Forbid();
  199.         sc = IntuitionBase->FirstScreen;
  200.         while((sc = sc->NextScreen) && sc != rd->rd_FirstScreen)
  201.           ;
  202.         if(sc)
  203.           ScreenToFront(sc);
  204.         Permit();
  205.       }
  206.     }
  207.     FreeScreenDrawInfo(rd->rd_Screen, rd->rd_DrawInfo);
  208.   }
  209.  
  210.   if(rd->rd_SelfScreen)
  211.     UnlockPubScreen(0, rd->rd_SelfScreen);
  212.   if(rd->rd_StringExtend.WorkBuffer)
  213.     FreeMem(rd->rd_StringExtend.WorkBuffer, passsize);
  214.  
  215.   return ticks;
  216. }
  217.  
  218. #ifdef __cplusplus
  219.   extern "C"
  220. #endif
  221.  
  222. LONG __asm LIBXpkPassRequest(register __a0 struct TagItem *ti)
  223. {
  224.   register struct RequestData *rd;
  225.   LONG err = 2, mode = 0;
  226.   struct TagItem *tags = ti;
  227.  
  228. #ifdef DEBUG
  229.   DebugTagList("XpkPassRequest", tags);
  230. #endif
  231.  
  232.   if(!(rd = AllocMem(sizeof(struct RequestData), MEMF_PUBLIC|MEMF_CLEAR)))
  233.     return XPKERR_NOMEM;
  234.  
  235. /* set defaults */
  236.   rd->rd_Time = 120;
  237.   rd->rd_PassUserData.pud_Flags = XPKPASSFLG_PRINTABLE;
  238.  
  239.   while((ti = NextTagItem(&tags)))
  240.   {
  241.     switch(ti->ti_Tag)
  242.     {
  243.     case XPK_PassChars: rd->rd_PassUserData.pud_Flags = ti->ti_Data; break;
  244.     case XPK_PasswordBuf:
  245.       rd->rd_GivenBuffer = (STRPTR) ti->ti_Data; mode += 10; break;
  246.     case XPK_PassBufSize: passsize = ti->ti_Data; break;
  247.     case XPK_Key16BitPtr:
  248.       rd->rd_GivenBuffer = (STRPTR) ti->ti_Data; mode += 11; break;
  249.     case XPK_Key32BitPtr:
  250.       rd->rd_GivenBuffer = (STRPTR) ti->ti_Data; mode += 12; break;
  251.     case XPK_PubScreen: rd->rd_Screen = (struct Screen *) ti->ti_Data; break;
  252.     case XPK_PassTitle: err |= 1; rd->rd_Title = (STRPTR) ti->ti_Data; break;
  253.     case XPK_TimeOut: err &= ~2; rd->rd_Time = ti->ti_Data; break;
  254.     case XPK_Preferences: if(!ti->ti_Data) err &= ~2; break;
  255.     };
  256.   }
  257.  
  258.   if(!mode || (mode > 12) || (mode == 10 && !passsize) ||
  259.   !rd->rd_GivenBuffer)
  260.   {
  261.     FreeMem(rd, sizeof(struct RequestData));
  262.     return XPKERR_BADPARAMS;
  263.   }
  264.  
  265.   if(err&2) // call the preferences
  266.   {
  267.     struct XpkPrefsSemaphore *sem;
  268.  
  269.     if((sem = GetPrefsSem()))
  270.     {
  271.       if(sem->xps_MainPrefs)
  272.         rd->rd_Time = sem->xps_MainPrefs->xmp_Timeout;
  273.       ReleaseSemaphore((struct SignalSemaphore *) sem);
  274.     }
  275.   }
  276.  
  277.   if(!(err&1)) /* create title text */
  278.   {
  279.     if(mode == 10)
  280.       rd->rd_Title = strings[TXT_REQ_PASSWORD];
  281.     else
  282.     {
  283.       rd->rd_Title = rd->rd_ScreenTitle;
  284.       sprintf(rd->rd_ScreenTitle, strings[TXT_REQ_KEY], (mode == 11 ? 16 : 32));
  285.     }
  286.   }
  287.  
  288.   if(mode > 10)
  289.   {
  290.     passsize = (mode == 11 ? 5 : 9);
  291.     passbuf = rd->rd_KeyBuffer;
  292.     rd->rd_PassUserData.pud_Flags = XPKPASSFLG_HEXADECIMAL;
  293.   }
  294.   else
  295.     passbuf = rd->rd_GivenBuffer;
  296.   
  297.   if(!(err = DoRequest(rd)))
  298.   {
  299.     if(mode == 11)
  300.       *((UWORD *) rd->rd_GivenBuffer) = strtoul(passbuf, 0, 16);
  301.     else if(mode == 12)
  302.       *((ULONG *) rd->rd_GivenBuffer) = strtoul(passbuf, 0, 16);
  303.   }
  304.  
  305.   FreeMem(rd, sizeof(struct RequestData));
  306.  
  307.   return err;
  308. }
  309.  
  310. #endif    /* XPKMASTER_PASSWORD_C */
  311.  
  312.